﻿using System.Data;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace Nardax.Data
{
    public interface ISqlDatabase : IDatabase<SqlCommand, SqlTransaction, SqlConnection>
    {
        /// <summary>
        /// Opens a connection to the database and returns the results of the command as an XmlReader object.
        /// </summary>
        /// <param name="command">The command to be executed.</param> 
        /// <param name="connection">The connection that will be used to execute the command on.</param>
        /// <returns>The XmlReader object that is created from the results of the command.</returns>
        /// <remarks>Working with the XmlReader requires an open connection but does not supply a way to close the
        /// connection when the reader is closed. So the caller is responsable for creating an open connection and then
        /// closing and displosing of the connection once the work with the XmlReader is complete.</remarks>
        XmlReader ExecuteXmlReader(SqlCommand command, SqlConnection connection);

        /// <summary>
        /// An asynchronous version of <see cref="ExecuteXmlReader"/>. Opens a connection to the database and returns the 
        /// results of the command as an XmlReader object.
        /// </summary>
        /// <param name="command">The command to be executed.</param> 
        /// <param name="connection">The connection that will be used to execute the command on.</param>
        /// <returns>The XmlReader object that is created from the results of the command.</returns>
        /// <remarks>Working with the XmlReader requires an open connection but does not supply a way to close the
        /// connection when the reader is closed. So the caller is responsable for creating an open connection and then
        /// closing and displosing of the connection once the work with the XmlReader is complete.</remarks>
        Task<XmlReader> ExecuteXmlReaderAsync(SqlCommand command, SqlConnection connection);

        /// <summary>
        /// An asynchronous version of <see cref="ExecuteXmlReader"/>. Opens a connection to the database and returns the 
        /// results of the command as an XmlReader object.
        /// </summary>
        /// <param name="command">The command to be executed.</param> 
        /// <param name="connection">The connection that will be used to execute the command on.</param>
        /// <param name="cancellationToken">The cancellation token that can be used to cancel the task.</param>
        /// <returns>The XmlReader object that is created from the results of the command.</returns>
        /// <remarks>Working with the XmlReader requires an open connection but does not supply a way to close the
        /// connection when the reader is closed. So the caller is responsable for creating an open connection and then
        /// closing and displosing of the connection once the work with the XmlReader is complete.</remarks>
        Task<XmlReader> ExecuteXmlReaderAsync(SqlCommand command, SqlConnection connection, CancellationToken cancellationToken);

        /// <summary>
        /// Uses the SqlBulkCopy class to move all of the data from the table provided to the table that is
        /// named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        void WriteToServer(string destinationTableName, DataTable table);

        /// <summary>
        /// An asynchronous version of <see cref="WriteToServer"/>. Uses the SqlBulkCopy class to move all 
        /// of the data from the table provided to the table that is named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        Task WriteToServerAsync(string destinationTableName, DataTable table);

        /// <summary>
        /// An asynchronous version of <see cref="WriteToServer"/>. Uses the SqlBulkCopy class to move all 
        /// of the data from the table provided to the table that is named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        /// <param name="cancellationToken">The cancellation token that can be used to cancel the task.</param>
        Task WriteToServerAsync(string destinationTableName, DataTable table, CancellationToken cancellationToken);

        /// <summary>
        /// Uses the SqlBulkCopy class to move all of the data from the table provided to the table that is
        /// named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        /// <param name="batchSize">The size of the batch that will be used while the bulk insert is executed.</param>
        void WriteToServer(string destinationTableName, DataTable table, int batchSize);

        /// <summary>
        /// An asynchronous version of <see cref="WriteToServer"/>. Uses the SqlBulkCopy class to move all 
        /// of the data from the table provided to the table that is named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        /// <param name="batchSize">The size of the batch that will be used while the bulk insert is executed.</param>
        Task WriteToServerAsync(string destinationTableName, DataTable table, int batchSize);

        /// <summary>
        /// An asynchronous version of <see cref="WriteToServer"/>. Uses the SqlBulkCopy class to move all 
        /// of the data from the table provided to the table that is named in the destinationTableName parameter.
        /// </summary>
        /// <param name="destinationTableName">Name of the destination table in the database.</param>
        /// <param name="table">The table with the data to be copied to the database.</param>
        /// <param name="batchSize">The size of the batch that will be used while the bulk insert is executed.</param>
        /// <param name="cancellationToken">The cancellation token that can be used to cancel the task.</param>
        Task WriteToServerAsync(string destinationTableName, DataTable table, int batchSize, CancellationToken cancellationToken);
    }
}